package com.panda.ServletDemo.controller;

import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;

import com.alibaba.fastjson.JSONObject;
import com.panda.ServletDemo.utils.ResultResponse;
import com.panda.ServletDemo.utils.ResultResponseUtil;
import com.panda.ServletDemo.utils.ThymeleafUtil;


public class BaseHttpServlet extends HttpServlet{
	
	private static final long serialVersionUID = -4258889972080106590L;
	
	private static final Logger logger = LoggerFactory.getLogger(BaseHttpServlet.class);
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.info("接收请求,请求类型为:{}",req.getMethod());
		
		//获取method参数，invoke()动态调用方法
		String methodName = req.getParameter("method");
		Method method = null;
		resp.setContentType("text/html;charset=utf-8"); 
		
		//保存webApp根目录
		req.getSession().setAttribute("contextPath", req.getContextPath());
		
	    try {
			method = this.getClass().getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
		} catch (Exception e) {
			logger.error(String.format("调用：%s方法不存在",methodName), e);
			resp.setStatus(HttpServletResponse.SC_NOT_FOUND);//404
			String isXHR = req.getHeader("X-Requested-With");
			if(isXHR == null){
				resp.sendRedirect(req.getContextPath()+"/templates/common/404.html");
			}else{
				JSONObject json = new JSONObject();
				json.put("msg",ResultResponseUtil.requsetNotFound("没有找到该方法").getMsg());
				json.put("code",ResultResponseUtil.requsetNotFound("没有找到该方法").getCode());//200
				json.put("data",ResultResponseUtil.requsetNotFound("没有找到该方法").getData());
				resp.setContentType("application/json;charset=utf-8");
				resp.getWriter().println(json.toString());
				resp.getWriter().flush();
			}
			return;
		}
		//反射调用方法
		Object result = null;
		try {
			result = (Object)method.invoke(this, req, resp);
		} catch (Exception e) {
			logger.error("反射调用方法:{}失败！",methodName);
			e.printStackTrace();
		} 	
		try {	
			if(result instanceof java.lang.String) {//返回视图
				String str = (String)result;
				int index = str.indexOf(":");//下标
				if(index == -1) {//转发
					
					TemplateEngine engine = ThymeleafUtil.templateEngine(req.getServletContext());
			        WebContext context = new WebContext(req, resp, req.getServletContext());        
					//保存值到thymeleaf模版中
			        context.setVariable("currentDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					//使用thymeleaf加载模版
			        engine.process(str, context, resp.getWriter());
					//req.getRequestDispatcher(str).forward(req, resp);
				} else {
					String prefix = str.substring(0, index);//前缀
					String path = str.substring(index + 1);//路径
					if(prefix.equals("r")) {//重定向
						resp.sendRedirect(req.getContextPath() + path);
					}
				}
			}
		} catch (Exception e) {
			logger.error(String.format("调用：%s方法失败",methodName), e);
			resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);//500
			resp.sendRedirect(req.getContextPath()+"/templates/common/500.html");
			return;
		}
		
		resp.setContentType("application/json;charset=utf-8");
		try {
			if(result instanceof ResultResponse){//返回json数据
				ResultResponse res = (ResultResponse)result;
				Object entity = res.getData();
				JSONObject json = new JSONObject();
				
				json.put("msg", res.getMsg());
				json.put("code",res.getCode());//200
				json.put("data", JSONObject.toJSON(entity) != null ? JSONObject.toJSON(entity) : null);
				
				resp.getWriter().println(json.toString());
				resp.getWriter().flush();
			}
		} catch (Exception e) {
			logger.error(String.format("调用：%s方法失败",method.getName()), e);
			resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);//500
			return;
		}
	}
}
